package vip.xiaonuo.biz.modular.nccAi.util;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.coze.openapi.client.workflows.run.RetrieveRunHistoryReq;
import com.coze.openapi.client.workflows.run.RetrieveRunHistoryResp;
import com.coze.openapi.client.workflows.run.RunWorkflowReq;
import com.coze.openapi.client.workflows.run.RunWorkflowResp;
import com.coze.openapi.client.workflows.run.model.WorkflowExecuteStatus;
import com.coze.openapi.client.workflows.run.model.WorkflowRunHistory;
import com.coze.openapi.service.auth.JWTOAuthClient;

import com.coze.openapi.service.auth.TokenAuth;
import com.coze.openapi.service.service.CozeAPI;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import vip.xiaonuo.common.exception.CommonException;
import vip.xiaonuo.dev.api.DevConfigApi;

import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Map;

/**
 * ClassName:CozeClient
 * Description:
 *
 * @Author:薛守立
 * @CreateTime:2025/4/15 8:51
 */
public class CozeClient {

    // 客户端Id
    private String jwtOauthClientID = "1167196733387";

    //客户端私钥
    private String jwtOauthPrivateKey  = "";

    // 客户端私钥地址
    private String jwtOauthPrivateKeyFilePath  = "";

    // 客户端公钥Id
    private String jwtOauthPublicKeyID  = "EdID2erU9wCYTPPtjsIcnzJgdZOdYRSxk0NBcwk7VjE";

    private String cozeAPIBase = "https://api.coze.cn";

    // token 地址
    public static String cozeToken = null;

    // api
    public static CozeAPI cozeApi = null;

    /** coze平台的过期时间 */
    private static long EXPIRES_TIME = 890 ;

    private static final String JWT_OAUTH_CLIENT_ID = "JWT_OAUTH_CLIENT_ID";

    private static final String JWT_OAUTH_PRIVATE_KEY_FILE_PATH = "JWT_OAUTH_PRIVATE_KEY_FILE_PATH";

    private static final String JWT_OAUTH_PUBLIC_KEY_ID = "JWT_OAUTH_PUBLIC_KEY_ID";

    private static final String COZE_KEY = "COZE_ACCESS_TOKEN";

    private static final String COZE_BASE_URL="https://api.coze.cn";

    private static Logger logger = LoggerFactory.getLogger(CozeClient.class);

    public CozeClient(String jwtOauthClientID, String jwtOauthPrivateKeyFilePath, String jwtOauthPublicKeyID, String cozeAPIBase) {
        this.jwtOauthClientID = jwtOauthClientID;
        this.jwtOauthPrivateKeyFilePath = jwtOauthPrivateKeyFilePath;
        this.jwtOauthPublicKeyID = jwtOauthPublicKeyID;
        this.cozeAPIBase = cozeAPIBase;
        try {
            this.jwtOauthPrivateKey =
                    new String(
                            Files.readAllBytes(Paths.get(jwtOauthPrivateKeyFilePath)), StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    public CozeClient(){
        try {
            this.initClient();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 执行coze工作流
     *
     * @param workFlowId
     * @param parameters
     * @return
     */
    public String runWorkFlowAsync(String workFlowId, Map<String, Object> parameters){
        RunWorkflowReq runWorkflowReq = new RunWorkflowReq();
        runWorkflowReq.setWorkflowID(workFlowId);
        runWorkflowReq.setIsAsync(true);
        runWorkflowReq.setParameters(parameters);
        RunWorkflowReq req = RunWorkflowReq.builder().workflowID(workFlowId).parameters(parameters).isAsync(true).build();
        RunWorkflowResp resp = cozeApi.workflows().runs().create(req);
        if(resp.getCode()==0 ){
            return resp.getExecuteID();
        }else{
            logger.info("coze接口执行错误：{}, debug网页地址为：{}",resp.getMsg(),resp.getDebugURL());
            throw new RuntimeException(resp.getMsg());
        }
    }

    /**
     * 查询工作流的执行情况
     *
     * @param workFlowId
     * @param executeId
     * @return
     */
    public String checkWorkFlow(String workFlowId, String executeId){
        RetrieveRunHistoryResp historyResp =
                cozeApi.workflows()
                        .runs()
                        .histories()
                        .retrieve(RetrieveRunHistoryReq.of(workFlowId, executeId));
        WorkflowRunHistory history = historyResp.getHistories().get(0);
        if(history.getExecuteStatus().equals(WorkflowExecuteStatus.FAIL)){
            logger.info("coze工作流接口执行错误：{}",history.getErrorMessage());
            throw new RuntimeException(history.getErrorMessage());
        }else if (history.getExecuteStatus().equals(WorkflowExecuteStatus.RUNNING)) {
            logger.info("coze工作流接口正在执行中：{}",history.getExecuteStatus());
            return "running";
        } else {
            logger.info("coze工作流接口执行成功，结果为：{}" , history.getOutput());
            return history.getOutput();
        }
    };

    /**
     * 充值coze的accesstoken
     */
    public void resetAccessToken(){
        ObjectMapper mapper = new ObjectMapper();
        // 文件配置相关属性
        DevConfigApi devConfigApi = SpringUtil.getBean(DevConfigApi.class);
        String clientId = devConfigApi.getValueByKey(JWT_OAUTH_CLIENT_ID);
        if(ObjectUtil.isEmpty(clientId)) {
            throw new CommonException("coze客户端未正确配置：clientId为空");
        }
        String filePath = devConfigApi.getValueByKey(JWT_OAUTH_PRIVATE_KEY_FILE_PATH);
        if(ObjectUtil.isEmpty(filePath)) {
            throw new CommonException("coze客户端未正确配置：私钥路径为空");
        }
        String publicKey = devConfigApi.getValueByKey(JWT_OAUTH_PUBLIC_KEY_ID);
        if(ObjectUtil.isEmpty(publicKey)) {
            throw new CommonException("coze客户端未正确配置：公钥Id为空");
        }
        try {
            String privateKey =new String(Files.readAllBytes(Paths.get(filePath)), StandardCharsets.UTF_8);
            JWTOAuthClient oauth =
                    new JWTOAuthClient.JWTOAuthBuilder()
                            .clientID(clientId)
                            .privateKey(privateKey)
                            .publicKey(publicKey)
                            .baseURL(COZE_BASE_URL)
                            .build();
            cozeToken = oauth.getAccessToken().getAccessToken();
        } catch (Exception e) {
            throw new CommonException(e.getMessage());
        }

    }
    /**
     * 初始化coze工作流客户端
     *
     * @throws Exception
     */
    public void initClient() {
        ObjectMapper mapper = new ObjectMapper();
        // 文件配置相关属性
        DevConfigApi devConfigApi = SpringUtil.getBean(DevConfigApi.class);
        String cozeAccessToken = devConfigApi.getToken(COZE_KEY);
        logger.info("cozeAccessToken 为：{}", cozeAccessToken);
        if(cozeAccessToken.isEmpty()){
            logger.info("缓存cozeAccessToken不存在，重新请求cozeAccessToken");
            this.resetAccessToken();
            /** 保存token */
            devConfigApi.saveToken(cozeToken, EXPIRES_TIME, COZE_KEY);
        }
        TokenAuth authCli = new TokenAuth(cozeToken);
        cozeApi = new CozeAPI.Builder().baseURL(COZE_BASE_URL).auth(authCli).readTimeout(10000).build();
    }
}
